package io.finer.erp.jeecg.bas.controller;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;

import cn.hutool.core.lang.UUID;
import io.finer.erp.jeecg.bas.dto.InventoryDTO;
import io.finer.erp.jeecg.bas.dto.MaterialContrastDTO;
import io.finer.erp.jeecg.bas.entity.BasMaterial;
import io.finer.erp.jeecg.bas.entity.BasMaterialLog;
import io.finer.erp.jeecg.bas.mapper.BasMaterialLogMapper;
import io.finer.erp.jeecg.bas.service.IBasMaterialLogService;
import io.finer.erp.jeecg.bas.service.IBasMaterialService;
import io.finer.erp.jeecg.bas.vo.BasMaterialLogVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

 /**
 * @Description: PDA物料盘点记录
 * @Author: jeecg-boot
 * @Date:   2021-05-11
 * @Version: V1.0
 */
@Api(tags="PDA物料盘点记录")
@RestController
@RequestMapping("/bas/basMaterialLog")
@Slf4j
public class BasMaterialLogController extends JeecgController<BasMaterialLog, IBasMaterialLogService> {
	@Autowired
	private IBasMaterialLogService basMaterialLogService;
	@Autowired
	private BasMaterialLogMapper materialLogMapper;
	@Autowired
	private IBasMaterialService materialService;
	
	/**
	 * 分页列表查询
	 *
	 * @param basMaterialLog
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "PDA物料盘点记录-分页列表查询")
	@ApiOperation(value="PDA物料盘点记录-分页列表查询", notes="PDA物料盘点记录-分页列表查询")
	@GetMapping(value = "/list")
	public Result<?> queryPageList(BasMaterialLog basMaterialLog,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<BasMaterialLog> queryWrapper = QueryGenerator.initQueryWrapper(basMaterialLog, req.getParameterMap());
		Page<BasMaterialLog> page = new Page<BasMaterialLog>(pageNo, pageSize);
		IPage<BasMaterialLog> pageList = basMaterialLogService.page(page, queryWrapper);
		return Result.ok(pageList);
	}
	
	@AutoLog(value = "实时库存-分页列表查询")
	@ApiOperation(value="实时库存-分页列表查询", notes="实时库存-分页列表查询")
	@GetMapping(value = "/inventoryList")
	public Result<?> queryInventoryList(BasMaterialLogVO vo,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		Page<InventoryDTO> page = new Page<InventoryDTO>(pageNo, pageSize);
		IPage<InventoryDTO> pageList = basMaterialLogService.getInventory(vo, page);
		return Result.ok(pageList);
	}
	
	/**
	 * @Description 物料盘点与实时库存数量对比列表查询
	 * @param basMaterialLog
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 * Create at: 2021-08-20 09:08:31
	 * @author: xzs
	 * Revision:
	 *    2021-08-20 09:08:31 - first revision by xzs
	 *
	 */
	@AutoLog(value = "物料盘点与实时库存数量对比列表查询")
	@ApiOperation(value="物料盘点与实时库存数量对比列表查询", notes="物料盘点与实时库存数量对比列表查询")
	@GetMapping(value = "/contrastlist")
	public Result<?> queryContrastList(BasMaterialLogVO basMaterialLog,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		Page<MaterialContrastDTO> pages = new Page<MaterialContrastDTO>(pageNo, pageSize);
		List<MaterialContrastDTO> pageList = basMaterialLogService.queryDTOList(basMaterialLog);
		return Result.ok(pages.setRecords(pageList));
	}
	
	/**
	 *   添加
	 *
	 * @param basMaterialLog
	 * @return
	 */
	@AutoLog(value = "PDA物料盘点记录-添加")
	@ApiOperation(value="PDA物料盘点记录-添加", notes="PDA物料盘点记录-添加")
	@PostMapping(value = "/add")
	public Result<?> add(@RequestBody BasMaterialLog basMaterialLog) {
		basMaterialLogService.save(basMaterialLog);
		return Result.ok("添加成功！");
	}
	
	/**
	 *  编辑
	 *
	 * @param basMaterialLog
	 * @return
	 */
	@AutoLog(value = "PDA物料盘点记录-编辑")
	@ApiOperation(value="PDA物料盘点记录-编辑", notes="PDA物料盘点记录-编辑")
	@PutMapping(value = "/edit")
	public Result<?> edit(@RequestBody BasMaterialLog basMaterialLog) {
		basMaterialLogService.updateById(basMaterialLog);
		return Result.ok("编辑成功!");
	}
	
	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "PDA物料盘点记录-通过id删除")
	@ApiOperation(value="PDA物料盘点记录-通过id删除", notes="PDA物料盘点记录-通过id删除")
	@DeleteMapping(value = "/delete")
	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
		basMaterialLogService.removeById(id);
		return Result.ok("删除成功!");
	}
	
	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "PDA物料盘点记录-批量删除")
	@ApiOperation(value="PDA物料盘点记录-批量删除", notes="PDA物料盘点记录-批量删除")
	@DeleteMapping(value = "/deleteBatch")
	public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.basMaterialLogService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.ok("批量删除成功!");
	}
	
	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "PDA物料盘点记录-通过id查询")
	@ApiOperation(value="PDA物料盘点记录-通过id查询", notes="PDA物料盘点记录-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
		BasMaterialLog basMaterialLog = basMaterialLogService.getById(id);
		if(basMaterialLog==null) {
			return Result.error("未找到对应数据");
		}
		return Result.ok(basMaterialLog);
	}

    /**
    * 导出excel
    *
    * @param request
    * @param basMaterialLog
    */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, BasMaterialLog basMaterialLog) {
        return super.exportXls(request, basMaterialLog, BasMaterialLog.class, "PDA物料盘点记录");
    }
    
    /**
     * @Description 物料盘点与实时库存数量对比导出
     * @param request
     * @param vo
     * @return
     * Create at: 2021-08-20 16:46:15
     * @author: xzs
     * Revision:
     *    2021-08-20 16:46:15 - first revision by xzs
     *
     */
    @RequestMapping(value = "/exportContrastXls")
    public ModelAndView exportContrastXls(HttpServletRequest request, BasMaterialLogVO vo) {
        return exportContrsXls(request, vo, MaterialContrastDTO.class, "物料盘点与实时库存数据对比");
    }
    
    private ModelAndView exportContrsXls(HttpServletRequest request, BasMaterialLogVO vo, Class<MaterialContrastDTO> clazz, String title) {
        // Step.1 当前登录人
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        // Step.2 获取导出数据
        List<MaterialContrastDTO> pageList = this.basMaterialLogService.queryDTOList(vo);
        List<MaterialContrastDTO> exportList = null;

        // 过滤选中数据
        String selections = request.getParameter("selections");
        if (oConvertUtils.isNotEmpty(selections)) {
            List<String> selectionList = Arrays.asList(selections.split(","));
            exportList = pageList.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
        } else {
            exportList = pageList;
        }

        // Step.3 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
        mv.addObject(NormalExcelConstants.CLASS, clazz);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title));
        mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
        return mv;
    }
    
    /**
     * @Description 实时库存导出
     * @param request
     * @param vo
     * @return
     * Create at: 2021-08-20 16:52:23
     * @author: xzs
     * Revision:
     *    2021-08-20 16:52:23 - first revision by xzs
     *
     */
    @RequestMapping(value = "/exportInventeryXls")
    public ModelAndView exportInventeryXls(HttpServletRequest request, BasMaterialLogVO vo) {
        return exportInXls(request, vo, InventoryDTO.class, "实时库存");
    }
    
    private ModelAndView exportInXls(HttpServletRequest request, BasMaterialLogVO vo, Class<InventoryDTO> clazz, String title) {
        // Step.1 当前登录人
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        // Step.2 获取导出数据
        List<String> ids = Lists.newArrayList();
		if(!StringUtils.isBlank(vo.getCategoryId())) {
			LambdaQueryWrapper<BasMaterial> query = new LambdaQueryWrapper<>();
			query.eq(BasMaterial::getCategoryId, vo.getCategoryId());
			List<BasMaterial> list = this.materialService.list(query);
			ids.add(UUID.randomUUID().toString());
			if(null != list && list.size() > 0) {
				for (BasMaterial mate : list) {
					ids.add(mate.getId());
				}
				vo.setIds(ids);
			}
		}
        List<InventoryDTO> pageList = this.materialLogMapper.getInventorySum(vo);
        List<InventoryDTO> exportList = null;

        // 过滤选中数据
        String selections = request.getParameter("selections");
        if (oConvertUtils.isNotEmpty(selections)) {
            List<String> selectionList = Arrays.asList(selections.split(","));
            exportList = pageList.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList());
        } else {
            exportList = pageList;
        }

        // Step.3 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
        mv.addObject(NormalExcelConstants.CLASS, clazz);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title));
        mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
        return mv;
    }
    
    /**
     * 获取对象ID
     *
     * @return
     */
    private String getId(MaterialContrastDTO item) {
        try {
            return PropertyUtils.getProperty(item, "id").toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * 获取对象ID
     *
     * @return
     */
    private String getId(InventoryDTO item) {
        try {
            return PropertyUtils.getProperty(item, "id").toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
      * 通过excel导入数据
    *
    * @param request
    * @param response
    * @return
    */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, BasMaterialLog.class);
    }
    
    
    @AutoLog(value = "PDA物料盘点记录-数量统计")
	@ApiOperation(value="PDA物料盘点记录-数量统计", notes="PDA物料盘点记录-数量统计")
	@GetMapping(value = "/queryQuantSum")
	public Result<?> queryQuantSum(BasMaterialLog basMaterialLog, HttpServletRequest req) {
		return basMaterialLogService.queryQuantSum(basMaterialLog, req);
	}
    
    @AutoLog(value = "PDA物料盘点记录-数量统计")
	@ApiOperation(value="PDA物料盘点记录-数量统计", notes="PDA物料盘点记录-数量统计")
	@GetMapping(value = "/queryInventSum")
	public Result<?> queryInventSum(BasMaterialLogVO vo) {
		return basMaterialLogService.queryInventSum(vo);
	}
    
    /**
     * @Description PDA物料盘点记录-物料查询控件列表
     * @param basMaterialLog
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     * Create at: 2021-05-22 16:00:38
     * @author: xzs
     * Revision:
     *    2021-05-22 16:00:38 - first revision by xzs
     *
     */
    @AutoLog(value = "PDA物料盘点记录-物料查询控件列表")
	@ApiOperation(value="PDA物料盘点记录-物料查询控件列表", notes="PDA物料盘点记录-物料查询控件列表")
	@GetMapping(value = "/queryList")
	public Result<?> queryList(BasMaterialLog basMaterialLog,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		QueryWrapper<BasMaterialLog> queryWrapper = QueryGenerator.initQueryWrapper(basMaterialLog, req.getParameterMap());
		queryWrapper.groupBy("name");
		Page<BasMaterialLog> page = new Page<BasMaterialLog>(pageNo, pageSize);
		IPage<BasMaterialLog> pageList = basMaterialLogService.page(page, queryWrapper);
		return Result.ok(pageList);
	}
    
    /**
     * @Description 替换--将盘点记录里的数量替换实时库存里的数量
     * @param basMaterialLog
     * @return
     * Create at: 2021-08-18 10:18:28
     * @author: xzs
     * Revision:
     *    2021-08-18 10:18:28 - first revision by xzs
     *
     */
    @AutoLog(value = "替换--将盘点记录里的数量替换实时库存里的数量")
	@ApiOperation(value="替换--将盘点记录里的数量替换实时库存里的数量", notes="替换--将盘点记录里的数量替换实时库存里的数量")
	@PutMapping(value = "/replaceQty")
	public Result<?> replaceQty(@RequestBody BasMaterialLog basMaterialLog) {
		basMaterialLogService.replaceQty(basMaterialLog);
		return Result.ok("替换成功!");
	}

}
